Skip to content

Conversation

xqin
Copy link
Contributor

@xqin xqin commented Jun 28, 2025

Pass the agent parameter to WebSocket to support accessing the target service through a proxy.

full example code:

import axios from 'axios'
import { HttpsProxyAgent } from 'https-proxy-agent'
import Lark from '@larksuiteoapi/node-sdk'


const httpsAgent = new HttpsProxyAgent('http://127.0.0.1:8899')
const httpInstance = axios.create({
  proxy: false,
  httpsAgent,
})

httpInstance.interceptors.request.use((req) => {
    if (req.headers) {
        req.headers['User-Agent'] = 'oapi-node-sdk/1.0.0';
    }
    return req;
}, undefined, { synchronous: true })

httpInstance.interceptors.response.use((resp) => resp.data)



const larkConfig = {
  appId: 'xxxx',
  appSecret: 'yyyyyyy',
  httpInstance, // <!---  custom httpInstance
  loggerLevel: Lark.LoggerLevel.debug,
}


const wsClient = new Lark.WSClient(larkConfig)

wsClient.start({
  eventDispatcher: new Lark.EventDispatcher({}).register({
    'im.message.receive_v1': async (data) => {
      console.log('Received message:', JSON.stringify(data, null, 2))
    }
  })
})

@mazhe-nerd
Copy link
Collaborator

mazhe-nerd commented Jun 30, 2025

感谢同学PR;如果直接从httpInstance上取agent,看起来会把wsclient和httpInstance耦合起来(agent还会分http和https的情况),如果给wsClient增加一个agent的构造参数好点儿?

@xqin
Copy link
Contributor Author

xqin commented Jul 1, 2025

wsclient 内部 也会通过 httpInstance 发送请求, 也是需要走代理的。

所以是 共用的同一个实例。

agent 分 http 和 https, 但现实中 HTTP 已经标记为不安全的, 且现在向 飞书 请求的时候,也不会走 HTTP, 所以 直接取的 httpsAgent 来做为 agent 。

      const { httpAgent, httpsAgent } = this.httpInstance.defaults;
      wsInstance = new WebSocket(connectUrl, { agent: httpsAgent || httpAgent });

本来想这么写的,后来想想 不会有 HTTP 的场景(本地开发 用HTTP时, 可以 不配置代理 就好了),就改成现在 PR 中的样子了。

给 WebSocket 配置代理的代码参考的这里:

https://github.com/TooTallNate/proxy-agents/tree/main/packages/https-proxy-agent#ws-websocket-connection-example

@mazhe-nerd
Copy link
Collaborator

默认取httpInstance的agent也是合理的,现在确实用了httpInstance来发起连接;

如果有需要将httpInstance和wsClient拆分开的场景,我们也可以增加构造参数来支持,且不引入break change;

这样改OK哈,不过还有2个地方:

  1. httpInstance的类型需要加下agent: https://github.com/larksuite/node-sdk/blob/main/typings/http.ts#L1
  2. package.json的version需要更新到1.52.0

@xqin
Copy link
Contributor Author

xqin commented Jul 1, 2025

好的,我再更新一下。

@xqin xqin force-pushed the main branch 2 times, most recently from faf34c3 to b827ff8 Compare July 1, 2025 10:29
@xqin
Copy link
Contributor Author

xqin commented Jul 1, 2025

项目中的 httpInstance 其实是 AxiosInstance,不清楚为什么单独定义了一个 HttpInstance 一个类型。

typings/http.ts 文件中 由于 缩进存在 “空格” 和 “Tab” 混用的情况,所以我把 “Tab” 我修改成了 两个空格, Review 的时候可以忽略 空白改动。

image

@mazhe-nerd
Copy link
Collaborator

单独定义了一个 HttpInstance 的原因是有的同学会自定义httpInstance,比如使用node-fetch,这样的话类型和参数就不能完全和axios对齐;我们只需要定义需要的接口即可。

同理,这里我们需要自定义一下defaults,避免和axios耦合:

defaults?: {
  httpAgent?: any;
  httpsAgent?: any;
}

@xqin
Copy link
Contributor Author

xqin commented Jul 1, 2025

好的,那我再修改一下。

@xqin xqin force-pushed the main branch 2 times, most recently from 0b34f31 to 26a9aab Compare July 1, 2025 11:00
@xqin
Copy link
Contributor Author

xqin commented Jul 1, 2025

根据刚才的回复,如果加 defaults 其实和 axios 绑定了。

所以 根据 前面的讨论, 感觉加个 agent 的可选参数, 更好一点。 麻烦你再看看, 现在这样改可以吗?


更新一下示例代码:

import axios from 'axios'
import { HttpsProxyAgent } from 'https-proxy-agent'
import Lark from '@larksuiteoapi/node-sdk'


const httpsAgent = new HttpsProxyAgent('http://127.0.0.1:8899')
const httpInstance = axios.create({
  proxy: false,
  httpsAgent,
})

httpInstance.interceptors.request.use((req) => {
    if (req.headers) {
        req.headers['User-Agent'] = 'oapi-node-sdk/1.0.0';
    }
    return req;
}, undefined, { synchronous: true })

httpInstance.interceptors.response.use((resp) => resp.data)



const larkConfig = {
  appId: 'xxxx',
  appSecret: 'yyyyyyy',
  httpInstance, // <!---  custom httpInstance
  loggerLevel: Lark.LoggerLevel.debug,
}


const wsClient = new Lark.WSClient({...larkConfig, agent: httpsAgent})

wsClient.start({
  eventDispatcher: new Lark.EventDispatcher({}).register({
    'im.message.receive_v1': async (data) => {
      console.log('Received message:', JSON.stringify(data, null, 2))
    }
  })
})

@mazhe-nerd mazhe-nerd merged commit 5b6bc81 into larksuite:main Jul 1, 2025
@mazhe-nerd
Copy link
Collaborator

包发好了:1.52.0,感谢同学贡献~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants